#include "GAF_Package.h"
#include "GAF_Define.h"
#include "GAF_Platform.h"

namespace GAF
{
	Package::PackageMap Package::ms_mapPackages;

	Package* Package::GetDefaultPackage(const STD_STRING strPathName)
	{
		Package* _pPackage = NULL;
		PackageMap::const_iterator _cit = ms_mapPackages.find(strPathName);
		if(_cit != ms_mapPackages.end())
			_pPackage = _cit->second;

		if(_pPackage == NULL)
		{
			GAF_CHECK_R(strPathName != "", NULL);

			STD_STRING _strKind = "";
			_pPackage = GAF_pTHEAPP->CreateDefaultPackage(_strKind);

			if(_pPackage == NULL)
			{
				_pPackage = GAF_NEW(Package);
				_strKind = GAF_PACKAGE_DISK;
			}

			if(!_pPackage->Load(strPathName, _strKind))
			{
				GAF_ERROR("Load \"%s\" Package Error!", strPathName.c_str());
				_pPackage->Release();

				if(_strKind == GAF_PACKAGE_DISK)
				{
					GAF_DELETE(_pPackage);
				}
				else
					GAF_pTHEAPP->DeleteDefaultPackage(_strKind, _pPackage);

				_pPackage = NULL;
			}

			if(_pPackage != NULL)
				ms_mapPackages.insert(PackageMap::value_type(strPathName, _pPackage));
		}

		return _pPackage;
	}

	bool Package::DestroyOne(STD_STRING strPathName)
	{
		Package* _pPackage = NULL;
		PackageMap::iterator _it = ms_mapPackages.find(strPathName);
		if(_it != ms_mapPackages.end())
			_pPackage = _it->second;
		ms_mapPackages.erase(_it);

		if(_pPackage == NULL)
			return false;

		_pPackage->Release();
		if(_pPackage->m_strKind == GAF_PACKAGE_DISK)
		{
			GAF_DELETE(_pPackage);
		}
		else
			GAF_pTHEAPP->DeleteDefaultPackage(_pPackage->m_strKind, _pPackage);

		return true;
	}

	bool Package::DestroyAll()
	{
		if(ms_mapPackages.size() > 0)
		{
			Package* _pPackage = NULL;

			for(PackageMap::iterator _it = ms_mapPackages.begin();
				_it != ms_mapPackages.end(); _it++)
			{
				_pPackage = _it->second;
				_it->second = NULL;

				if(_pPackage != NULL)
				{
					_pPackage->Release();
					if(_pPackage->m_strKind == GAF_PACKAGE_DISK)
					{
						GAF_DELETE(_pPackage);
					}
					else
						GAF_pTHEAPP->DeleteDefaultPackage(_pPackage->m_strKind, _pPackage);
				}
			}

			ms_mapPackages.clear();
		}

		return true;
	}



	Package::Package() :
		m_strPath(""),
		m_strKind(""),
		m_nResCount(-1)
	{

	}

	Package::~Package()
	{

	}

	bool Package::Load(STD_STRING strPathName, STD_STRING strKind)
	{
		GAF_CHECK_R(strPathName != "", false);

		m_strPath = strPathName;
		m_strKind = strKind;

		if(m_strKind != GAF_PACKAGE_DISK)
		{
			STD_STRING strName = m_strPath + "." + m_strKind;
			if(OnLoad(strName) == true)
				return true;
		}

		STD_STRING _strPathFiles = m_strPath;
		_strPathFiles += "/*.*";

		// 获取资源文件夹文件数
		m_nResCount = 0;

		// 检查磁盘目录
		SYS_FS_DIR _dir;
		SYS_FS_DATA _data;
		SYS_FS_OPEN(_strPathFiles.c_str(), _dir, _data);

		if(_dir == SYS_FS_ERROR)
		{
			GAF_ERROR("Load \"%s\" Disk Pack Is No Find!", m_strPath.c_str());
			return false;
		}
		if(m_strKind != GAF_PACKAGE_DISK)
		{
			GAF_WARM("Load \"%s\" Package Turn To Disk Path!", m_strPath.c_str());
		}
		m_strKind = GAF_PACKAGE_DISK;

		do 
		{
			if(SYS_FS_DATA_ISKIND(_data, SYS_FS_KIND_FILE))
				m_nResCount++;
		}while(SYS_FS_READ(_dir, _data) != SYS_FS_ERROR);
		SYS_FS_CLOSE(_dir);

		return true;
	}

	ImageHandle Package::GetImageHandle(const STD_STRING strImageName, _OUT ImageInfo& ii)
	{
		ImageHandle _hImage = NULL;

		ImageHandleMap::const_iterator _cit = m_mapImageHandles.find(strImageName);
		if(_cit != m_mapImageHandles.end())
			_hImage = _cit->second;

		if(_hImage != NULL)
		{
			GAF_pTHEPLATFORM->GetImageInfo(_hImage, ii);
			return _hImage;
		}

#ifdef GAF_RES_DISK_FIRST
		STD_STRING _strName = m_strPath + "/" + strImageName;
		_hImage = GAF_pTHEPLATFORM->NewImage(_strName, ii);
		if(_hImage == NULL)
#endif
		{
#ifndef GAF_RES_DISK_FIRST
			if(m_strKind == GAF_PACKAGE_DISK)
			{
				STD_STRING _strPathName = m_strPath + "/" + strImageName;
				_hImage = BASE(Package*) OnLoadImageHandle(_strPathName, ii);
			}
			else
#endif
			{
				_hImage = OnLoadImageHandle(strImageName, ii);
			}
		}

		if(_hImage != NULL)
		{
			m_mapImageHandles.insert(ImageHandleMap::value_type(strImageName, _hImage));
		}

		return _hImage;
	}

	Image* Package::GetImage(const STD_STRING strImageName)
	{
		ImageInfo _ii;
		ImageHandle _hImage = GetImageHandle(strImageName, _ii);

		if(_hImage == NULL)
			return NULL;

		Image* _pImage = Image::Create(_hImage, _ii);

		return _pImage;
	}

	bool Package::Release()
	{
		if(OnRelease() == false)
		{
			if(m_mapImageHandles.size() > 0)
			{
				ImageHandle _hImage = NULL;

				for(ImageHandleMap::iterator _it = m_mapImageHandles.begin();
					_it != m_mapImageHandles.end(); _it++)
				{
					_hImage = _it->second;
					_it->second = NULL;

					if(_hImage != NULL)
					{
						OnDestroyImageHandle(_hImage);
					}
				}

				m_mapImageHandles.clear();
			}
		}
		return true;
	}

	STD_STRING Package::GetPath()
	{
		return m_strPath;
	}

	STD_STRING Package::GetKind()
	{
		return m_strKind;
	}

	int Package::GetCount()
	{
		return m_nResCount;
	}

	ImageHandle Package::OnLoadImageHandle(const STD_STRING strImageName, _OUT ImageInfo& ii)
	{
		return GAF_pTHEPLATFORM->NewImage(strImageName, ii);
	}

	bool Package::OnDestroyImageHandle(ImageHandle hImage)
	{
		return GAF_pTHEPLATFORM->DeleteImage(hImage);
	}

}
